﻿#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using ESF.General.Entity;
using System.Data.Linq.Mapping;
using System.Data.Linq;
using System.IO;
using System.Xml;
using ESF.General;

#endregion

namespace ESF.DMS.Entities
{
	[DataContract]
	[Serializable]
	public class FileReference : BaseEntity, IEquatable<FileReference>, IAuditableEntity, IPagginableInfo
	{
		#region Properties

		[DataMember]
		public int? ID { set; get; }

		[DataMember]
		public string Description { set; get; }

		[DataMember]
		public BasicReference FileType { set; get; }

		[DataMember]
		public FileReference ParentFileReference { set; get; }

		[DataMember]
		public BasicReference MonitoredDirectorySubCategory { set; get; }

		[DataMember]
		public BasicReference MonitoredDirectory { set; get; }

		[DataMember]
		public string URL { set; get; }

		[DataMember]
		public string URLMD5 { set; get; }

		[DataMember]
		public long? LengthBytes { set; get; }


		[DataMember]
		public string ImageFormat { set; get; }

		[DataMember]
		public DateTime? CreationDateTime { set; get; }

		[DataMember]
		public DateTime? LastWriteDateTime { set; get; }

		[DataMember]
		public DateTime? LastUpdateDateTime { set; get; }

		[DataMember]
		public DateTime? VersionDateTime { set; get; }

		[DataMember]
		public IEnterprise Enterprise { set; get; }


		#region IsEnabled

		[DataMember]
		public bool IsEnabled;

		[DataMember]
		public string IsEnabledUserAlias;

		[DataMember]
		public DateTime? IsEnabledDateTime;

		#endregion


		#region Use

		[DataMember]
		public int? DownloadCount;

		[DataMember]
		public string LastDownloadUserAlias;

		[DataMember]
		public DateTime? LastDownloadDateTime;

		[DataMember]
		public int? OpenCount;

		[DataMember]
		public string LastOpenUserAlias;

		[DataMember]
		public DateTime? LastOpenDateTime;

		[DataMember]
		public string LastMoveToSubCategoryUserAlias;

		[DataMember]
		public DateTime? LastMoveToSubCategoryDateTime;

		[DataMember(Name = "LastUpdateAction")]
		public string LastUpdateAction;

		#endregion


		#region Extra

		public string calName { get { return Path.GetFileName(URL); } }

		public string calShowLengthBytes { get { return TextHelper.ToStringBytes(LengthBytes); } }

		#endregion


		[DataMember]
		public List<FileReferenceLevel> Levels { set; get; }
		
		[DataMember]
		public string OnlyName { set; get; }

		[DataMember]
		public string OnlyExtension { set; get; }

		[DataMember]
		public int? ItemsCount { set; get; }

		#endregion


		#region Contenido

		[DataMember]
		public string String64Contents { set; get; }

		[DataMember]
		public BasicReference asoBasicReferenceItem { set; get; }

		#endregion


		#region Filtro

		public DateTime? filCreationDateTimeStart;
		public DateTime? filCreationDateTimeEnd;

		public DateTime? filLastWriteDateTimeStart;
		public DateTime? filLastWriteDateTimeEnd;

		public string [] filMultiSearchGeneral;

		public string [] filMultiOnlyName;

		#endregion


		#region Relacionados

		public List<FileReference> Related;

		#endregion


		#region Extras

		public string calExtraInfo;

		public long ReadProcessingTimeMs;

		#endregion


		#region Constructor

		public FileReference()
		{
			Related = new List<FileReference>();

			Levels = new List<FileReferenceLevel> ();

			MonitoredDirectory = new BasicReference ();

			Enterprise = new BaseEnterprise ();

			IsEnabled = true;
		}


		public FileReference(FileInfo pFile)
			: this()
		{
			DirectoryInfo dir;


			URL = pFile.FullName;

			LastUpdateDateTime = DateTime.Now;

			if (pFile.Exists)
			{
				LengthBytes = pFile.Length;

				LastWriteDateTime = pFile.LastWriteTime;

				CreationDateTime = pFile.CreationTime;

				FileType = new BasicReference()
				{
					Code = pFile.Extension.ToLower(),
					Name = string.Format("Archivos de tipo {0}", pFile.Extension.ToLower())
				};

				OnlyName = FileHelper.GetFileNameFirstPoint(pFile.Name);

				OnlyExtension = FileHelper.GetFileNameExtensionFromFirstPoint(pFile.Name);
			}
			else if (Directory.Exists(pFile.FullName))
			{
				dir = new DirectoryInfo(pFile.FullName);

				LastWriteDateTime = dir.LastWriteTime;

				CreationDateTime = dir.CreationTime;
			}
		}

		#endregion


		#region Funciones

		/// <summary>
		/// Retorna a partir de la primer carpeta fuera de la pBasePath un listado con los nombres de carpeta
		/// </summary>
		/// <param name="pBasePath"></param>
		/// <returns></returns>
		public string[] GetFolderLevels(string pBasePath)
		{
			string tempURL;


			if (!URL.StartsWith(pBasePath, StringComparison.InvariantCultureIgnoreCase))
			{
				throw new Exception(string.Format("The URL {0} must start with {1} in order to get the folder levels", URL, pBasePath));
			}

			pBasePath = FileHelper.AddFinalSeparator(pBasePath);

			tempURL = Path.GetDirectoryName(URL).Replace(pBasePath, string.Empty);

			return tempURL.Split(Path.DirectorySeparatorChar);
		}


		public override bool Equals(object pObj)
		{
			if (pObj is FileReference)
			{
				return Equals(pObj as FileReference);
			}

			return false;
		}


		public bool Equals (FileReference pOther)
		{
			if (pOther == null) { return false; }
			
			return (string.Compare (pOther.URL, URL, true) == 0
				&& pOther.LengthBytes == LengthBytes 
				&& Math.Abs (((TimeSpan)(pOther.LastWriteDateTime - LastWriteDateTime)).TotalMilliseconds) < 200);	
		}


		public override int GetHashCode()
		{
			if (ID != null) { return ID.GetHashCode(); }

			if (URL != null) { return URL.GetHashCode(); }

			return 0;
		}

		#endregion


		public string UserCreationAlias
		{
			get
			{
				return string.Empty;
			}
			set
			{

			}
		}

		public string UserLastUpdateAlias
		{
			get
			{
				return string.Empty;

			}
			set
			{

			}
		}
	}
}
